<template>
  <scroll-view
    class="refresh-list"
    scroll-y
    :refresher-enabled="enableRefresh"
    :refresher-triggered="isRefreshing"
    :refresher-threshold="refreshThreshold"
    :refresher-default-style="refresherDefaultStyle"
    :refresher-background="refresherBackground"
    @refresherrefresh="handleRefresh"
    @refresherrestore="handleRefreshRestore"
    @scrolltolower="handleLoadMore"
    @scroll="handleScroll"
  >
    <!-- 自定义下拉刷新指示器 -->
    <template v-if="customRefreshIndicator">
      <view class="custom-refresh-indicator" :class="{ 'active': isRefreshing }">
        <view class="refresh-icon">
          <uni-icons 
            :type="isRefreshing ? 'spinner-cycle' : 'arrowdown'" 
            :class="{ 'rotating': isRefreshing }"
            size="20" 
            color="var(--primary-color)"
          ></uni-icons>
        </view>
        <text class="refresh-text">
          {{ isRefreshing ? refreshingText : pullToRefreshText }}
        </text>
      </view>
    </template>

    <!-- 列表内容 -->
    <view class="list-content">
      <slot></slot>
    </view>

    <!-- 加载更多指示器 -->
    <view v-if="showLoadMore" class="load-more-container">
      <template v-if="loadMoreStatus === 'loading'">
        <view class="load-more-loading">
          <view class="loading-dots">
            <view class="dot" v-for="n in 3" :key="n"></view>
          </view>
          <text class="load-more-text">{{ loadingText }}</text>
        </view>
      </template>
      
      <template v-else-if="loadMoreStatus === 'nomore'">
        <view class="load-more-nomore">
          <view class="divider-line"></view>
          <text class="load-more-text">{{ noMoreText }}</text>
          <view class="divider-line"></view>
        </view>
      </template>
      
      <template v-else-if="loadMoreStatus === 'error'">
        <view class="load-more-error" @click="handleLoadMore">
          <uni-icons type="refresh" size="16" color="var(--error-color)"></uni-icons>
          <text class="load-more-text">{{ errorText }}</text>
        </view>
      </template>
    </view>

    <!-- 回到顶部按钮 -->
    <view 
      v-if="showBackToTop && scrollTop > backToTopThreshold"
      class="back-to-top"
      @click="scrollToTop"
    >
      <uni-icons type="arrowup" size="20" color="#fff"></uni-icons>
    </view>
  </scroll-view>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';

interface Props {
  // 下拉刷新相关
  enableRefresh?: boolean;
  customRefreshIndicator?: boolean;
  refreshThreshold?: number;
  refresherDefaultStyle?: string;
  refresherBackground?: string;
  pullToRefreshText?: string;
  refreshingText?: string;
  
  // 上拉加载相关
  showLoadMore?: boolean;
  loadMoreStatus?: 'loading' | 'nomore' | 'error' | 'more';
  loadingText?: string;
  noMoreText?: string;
  errorText?: string;
  
  // 回到顶部相关
  showBackToTop?: boolean;
  backToTopThreshold?: number;
}

const props = withDefaults(defineProps<Props>(), {
  enableRefresh: true,
  customRefreshIndicator: false,
  refreshThreshold: 45,
  refresherDefaultStyle: 'none',
  refresherBackground: 'transparent',
  pullToRefreshText: '下拉刷新',
  refreshingText: '正在刷新...',
  
  showLoadMore: true,
  loadMoreStatus: 'more',
  loadingText: '加载中...',
  noMoreText: '没有更多了',
  errorText: '加载失败，点击重试',
  
  showBackToTop: true,
  backToTopThreshold: 400,
});

const emit = defineEmits<{
  refresh: [];
  loadMore: [];
  scroll: [scrollTop: number];
}>();

const isRefreshing = ref(false);
const scrollTop = ref(0);

const handleRefresh = () => {
  isRefreshing.value = true;
  emit('refresh');
};

const handleRefreshRestore = () => {
  isRefreshing.value = false;
};

const handleLoadMore = () => {
  if (props.loadMoreStatus === 'loading' || props.loadMoreStatus === 'nomore') {
    return;
  }
  emit('loadMore');
};

const handleScroll = (e: any) => {
  scrollTop.value = e.detail.scrollTop;
  emit('scroll', e.detail.scrollTop);
};

const scrollToTop = () => {
  // 使用页面滚动API
  uni.pageScrollTo({
    scrollTop: 0,
    duration: 300
  });
  
  // 触觉反馈
  uni.vibrateShort({
    type: 'light'
  });
};

// 暴露方法给父组件
const stopRefresh = () => {
  isRefreshing.value = false;
};

defineExpose({
  stopRefresh,
  scrollToTop,
});
</script>

<style lang="scss" scoped>
@import '@/styles/variables.scss';

.refresh-list {
  height: 100%;
  position: relative;
}

// 自定义下拉刷新指示器
.custom-refresh-indicator {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--spacing-lg);
  background-color: var(--background-color);
  transition: all var(--transition-normal) ease;
  
  &.active {
    background-color: var(--card-background);
  }
  
  .refresh-icon {
    margin-bottom: var(--spacing-sm);
    
    .rotating {
      animation: rotate 1s linear infinite;
    }
  }
  
  .refresh-text {
    font-size: var(--font-size-sm);
    color: var(--text-color-secondary);
  }
}

.list-content {
  min-height: 100%;
}

// 加载更多容器
.load-more-container {
  padding: var(--spacing-lg);
  display: flex;
  justify-content: center;
  align-items: center;
}

.load-more-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--spacing-sm);
  
  .loading-dots {
    display: flex;
    gap: var(--spacing-xs);
    
    .dot {
      width: 6px;
      height: 6px;
      border-radius: var(--border-radius-round);
      background-color: var(--primary-color);
      animation: bounce 1.4s infinite ease-in-out both;
      
      &:nth-child(1) { animation-delay: -0.32s; }
      &:nth-child(2) { animation-delay: -0.16s; }
      &:nth-child(3) { animation-delay: 0s; }
    }
  }
  
  .load-more-text {
    font-size: var(--font-size-sm);
    color: var(--text-color-secondary);
  }
}

.load-more-nomore {
  display: flex;
  align-items: center;
  gap: var(--spacing-md);
  width: 100%;
  
  .divider-line {
    flex: 1;
    height: 1px;
    background-color: var(--border-color-light);
  }
  
  .load-more-text {
    font-size: var(--font-size-sm);
    color: var(--text-color-placeholder);
    white-space: nowrap;
  }
}

.load-more-error {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
  padding: var(--spacing-sm) var(--spacing-md);
  border-radius: var(--border-radius);
  background-color: var(--card-background);
  border: 1px solid var(--error-color);
  cursor: pointer;
  transition: all var(--transition-fast) ease;
  
  &:active {
    transform: scale(0.98);
    opacity: 0.8;
  }
  
  .load-more-text {
    font-size: var(--font-size-sm);
    color: var(--error-color);
  }
}

// 回到顶部按钮
.back-to-top {
  position: fixed;
  right: var(--spacing-lg);
  bottom: calc(var(--spacing-xl) + var(--safe-area-inset-bottom));
  width: 44px;
  height: 44px;
  border-radius: var(--border-radius-round);
  background-color: var(--primary-color);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow);
  z-index: var(--z-index-fixed);
  cursor: pointer;
  transition: all var(--transition-normal) ease;
  animation: fadeIn var(--transition-normal) ease;
  
  &:active {
    transform: scale(0.9);
    background-color: var(--primary-dark);
  }
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

@keyframes bounce {
  0%, 80%, 100% {
    transform: scale(0);
  }
  40% {
    transform: scale(1);
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
</style>